#include "stddef.h"
#include "string.h"
#include "cpuid.h"

/* ==============================================
 * === ALIGNED SSE2 MEMORY CLEARING OPERATIONS ==
 * ============================================== */

const void * memclr_sse2(const void * const m_start, const size_t m_count)
{
	size_t i;

	if(((size_t)m_start) & (SSE_XMM_SIZE - 1))
	{
		i = 0;

		/* lets make sure we don't copy 'too' many bytes (i < m_count) */
		while(((((size_t)m_start) + i) & (SSE_XMM_SIZE - 1)) && i < m_count)
		{
			asm("stosb;" :: "D"(((size_t)m_start) + i), "a"((size_t)(0)));
			i++;
		}
	}
	else
	{
		i = 0;
	}

	for(; i + 64 <= m_count; i += 64)
	{
		asm volatile("	pxor %%xmm0, %%xmm0;	"
					 "	movntdq %%xmm0, 0(%0);	"
					 "	movntdq %%xmm0, 16(%0);	"
					 "	movntdq %%xmm0, 32(%0);	"
					 "	movntdq %%xmm0, 48(%0);	"
					 :: "r"(((size_t)m_start) + i));
	}

	asm(" rep stosb; " :: "a"((size_t)(0)), "D"(((size_t)m_start) + i), "c"(m_count - i));
	i += m_count - i;

	return (void *)(((size_t)m_start) + i);
}

/* =================================================
 * === ALIGNED NON-SSE MEMORY CLEARING OPERATIONS ==
 * ================================================= */
const void * memclr_std(const void * const m_start, const size_t m_count)
{
	size_t i;

	for(i = 0; i < m_count; i++)
	{
		*(uint8_t*)(((size_t)m_start) + i) = 0;
	}

	return (void *)(((size_t)m_start) + m_count);
}

void memset(const void * const dest, const uint8_t val, const size_t count)
{
    static size_t tmp;
    tmp = val;
    tmp |= ((tmp << 24) | (tmp << 16) | (tmp << 8));

    asm("rep stosl;"::"a"(tmp),"D"((size_t)dest),"c"(count / 4));
    asm("rep stosb;"::"a"(val),"D"(((size_t)dest) + ((count / 4) * 4)),"c"(count - ((count / 4) * 4)));
}









